package com.huawei.esdk.tp.professional.local.impl.service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.cxf.common.util.StringUtils;
import org.apache.log4j.Logger;

import com.huawei.esdk.platform.professional.local.constant.PlatformNativeConstant;
import com.huawei.esdk.tp.professional.local.bean.AddSiteInfoEx;
import com.huawei.esdk.tp.professional.local.bean.AuxStreamInfoEx;
import com.huawei.esdk.tp.professional.local.bean.CameraControlEx;
import com.huawei.esdk.tp.professional.local.bean.CtrlCameraEx;
import com.huawei.esdk.tp.professional.local.bean.DeleteSiteInfoEx;
import com.huawei.esdk.tp.professional.local.bean.EditSiteInfoEx;
import com.huawei.esdk.tp.professional.local.bean.IsConnectAuxSourceEx;
import com.huawei.esdk.tp.professional.local.bean.IsConnectAuxSourceExResponse;
import com.huawei.esdk.tp.professional.local.bean.IsReceiveRemAuxStrmEx;
import com.huawei.esdk.tp.professional.local.bean.IsReceiveRemAuxStrmExResponse;
import com.huawei.esdk.tp.professional.local.bean.IsSendAuxStreamEx;
import com.huawei.esdk.tp.professional.local.bean.IsSendAuxStreamExResponse;
import com.huawei.esdk.tp.professional.local.bean.QueryAuxStreamSourcesEx;
import com.huawei.esdk.tp.professional.local.bean.QueryAuxStreamSourcesExResponse;
import com.huawei.esdk.tp.professional.local.bean.QueryConfigEx;
import com.huawei.esdk.tp.professional.local.bean.QueryMainStreamSourcesEx;
import com.huawei.esdk.tp.professional.local.bean.QueryMainStreamSourcesExResponse;
import com.huawei.esdk.tp.professional.local.bean.QuerySiteVersionInfoEx;
import com.huawei.esdk.tp.professional.local.bean.QuerySiteVersionInfoExResponse;
import com.huawei.esdk.tp.professional.local.bean.QuerySitesInfoEx;
import com.huawei.esdk.tp.professional.local.bean.QuerySitesInfoExResponse;
import com.huawei.esdk.tp.professional.local.bean.QueryVideoOutSrcStateEx;
import com.huawei.esdk.tp.professional.local.bean.QueryVideoOutSrcStateExResponse;
import com.huawei.esdk.tp.professional.local.bean.SetAuxStreamEx;
import com.huawei.esdk.tp.professional.local.bean.SetMainAuxStreamSourcesEx;
import com.huawei.esdk.tp.professional.local.bean.SetVideoOutSrcEx;
import com.huawei.esdk.tp.professional.local.bean.SiteDeviceVersionInfoEx;
import com.huawei.esdk.tp.professional.local.bean.TPProfessionalSiteMgr;
import com.huawei.esdk.tp.professional.local.bean.TPSDKResponseEx;
import com.huawei.esdk.tp.professional.local.bean.TPSDKResponseWithPageEx;
import com.huawei.esdk.tp.professional.local.bean.TerminalInfoEx;
import com.huawei.esdk.tp.professional.local.bean.VideoSourcesInfoEx;
import com.huawei.esdk.tp.professional.local.impl.utils.ClientProvider;
import com.huawei.esdk.tp.professional.local.impl.utils.Encrypt;
import com.huawei.esdk.tp.professional.local.impl.utils.ExceptionUtils;
import com.huawei.esdk.tp.professional.local.site.SiteServiceEx;

public class SiteServiceExImpl implements SiteServiceEx
{
    /**
     * 日志对象
     */
    private static final Logger LOGGER = Logger.getLogger(SiteServiceExImpl.class);
    
    private TPProfessionalSiteMgr tPProfessionalSiteMgr =
        (TPProfessionalSiteMgr)ClientProvider.getClient(TPProfessionalSiteMgr.class);
    
    private static SiteServiceExImpl instance = null;
    
    public static synchronized SiteServiceExImpl getInstance()
    {
        if (null == instance)
        {
            instance = new SiteServiceExImpl();
        }
        return instance;
    }
    
    public TPSDKResponseEx<Integer> isConnectAuxSourceEx(String siteURI)
    {
        LOGGER.info("isConnectAuxSourceEx method start");
        TPSDKResponseEx<Integer> resp = new TPSDKResponseEx<Integer>();
        IsConnectAuxSourceEx isConnectAuxSourceEx = new IsConnectAuxSourceEx();
        IsConnectAuxSourceExResponse isConnectAuxSourceExResp;
        isConnectAuxSourceEx.setSiteUri(siteURI);
        try
        {
            isConnectAuxSourceExResp = tPProfessionalSiteMgr.isConnectAuxSourceEx(isConnectAuxSourceEx);
        }
        catch (Exception e)
        {
            LOGGER.error("isConnectAuxSourceEx method error", e);
            ExceptionUtils.processSoapException(resp, e);
            return resp;
        }
        Integer resultCode = isConnectAuxSourceExResp.getResultCode();
        resp.setResult(0 == resultCode ? isConnectAuxSourceExResp.getResult() : null);
        resp.setResultCode(resultCode);
        LOGGER.info("isConnectAuxSourceEx method end");
        return resp;
    }
    
    public TPSDKResponseEx<Integer> isSendAuxStreamEx(String siteURI)
    {
        LOGGER.info("isSendAuxStreamEx method start");
        TPSDKResponseEx<Integer> resp = new TPSDKResponseEx<Integer>();
        IsSendAuxStreamEx isSendAuxStreamEx = new IsSendAuxStreamEx();
        IsSendAuxStreamExResponse isSendAuxStreamExResp;
        isSendAuxStreamEx.setSiteUri(siteURI);
        try
        {
            isSendAuxStreamExResp = tPProfessionalSiteMgr.isSendAuxStreamEx(isSendAuxStreamEx);
        }
        catch (Exception e)
        {
            LOGGER.error("isSendAuxStreamEx method error", e);
            ExceptionUtils.processSoapException(resp, e);
            return resp;
        }
        Integer resultCode = isSendAuxStreamExResp.getResultCode();
        resp.setResult(0 == resultCode ? isSendAuxStreamExResp.getResult() : null);
        resp.setResultCode(resultCode);
        LOGGER.info("isSendAuxStreamEx method end");
        return resp;
    }
    
    public TPSDKResponseEx<Integer> isReceiveRemAuxStrmEx(String siteURI)
    {
        LOGGER.info("isReceiveRemAuxStrmEx method start");
        TPSDKResponseEx<Integer> resp = new TPSDKResponseEx<Integer>();
        IsReceiveRemAuxStrmEx isReceiveRemAuxStrmEx = new IsReceiveRemAuxStrmEx();
        IsReceiveRemAuxStrmExResponse isReceiveRemAuxStrmExResp;
        isReceiveRemAuxStrmEx.setSiteUri(siteURI);
        try
        {
            isReceiveRemAuxStrmExResp = tPProfessionalSiteMgr.isReceiveRemAuxStrmEx(isReceiveRemAuxStrmEx);
        }
        catch (Exception e)
        {
            LOGGER.error("isReceiveRemAuxStrmEx method error", e);
            ExceptionUtils.processSoapException(resp, e);
            return resp;
        }
        Integer resultCode = isReceiveRemAuxStrmExResp.getResultCode();
        resp.setResult(0 == resultCode ? isReceiveRemAuxStrmExResp.getResult() : null);
        resp.setResultCode(resultCode);
        LOGGER.info("isReceiveRemAuxStrmEx method end");
        return resp;
    }
    
    public Integer setAuxStreamEx(String siteUri, Integer controlCode)
    {
        LOGGER.info("setAuxStreamEx method start");
        SetAuxStreamEx setAuxStreamEx = new SetAuxStreamEx();
        setAuxStreamEx.setSiteUri(siteUri);
        setAuxStreamEx.setControlCode(controlCode);
        try
        {
            Integer errorCode = tPProfessionalSiteMgr.setAuxStreamEx(setAuxStreamEx).getResultCode();
            LOGGER.info("setAuxStreamEx method end");
            return errorCode;
        }
        catch (Exception e)
        {
            LOGGER.error("setAuxStreamEx method error", e);
            return ExceptionUtils.processSoapException(e);
        }
    }
    
    public TPSDKResponseEx<Map<Integer, String>> queryAuxStreamSourcesEx(String siteURI)
    {
        LOGGER.info("queryAuxStreamSourcesEx method start");
        TPSDKResponseEx<Map<Integer, String>> resp = new TPSDKResponseEx<Map<Integer, String>>();
        QueryAuxStreamSourcesEx queryAuxStreamSourcesEx = new QueryAuxStreamSourcesEx();
        QueryAuxStreamSourcesExResponse queryAuxStreamSourcesExResp;
        queryAuxStreamSourcesEx.setSiteUri(siteURI);
        try
        {
            queryAuxStreamSourcesExResp = tPProfessionalSiteMgr.queryAuxStreamSourcesEx(queryAuxStreamSourcesEx);
        }
        catch (Exception e)
        {
            LOGGER.error("queryAuxStreamSourcesEx method error", e);
            ExceptionUtils.processSoapException(resp, e);
            return resp;
        }
        Integer resultCode = queryAuxStreamSourcesExResp.getResultCode();
        resp.setResultCode(resultCode);
        if (0 == resultCode)
        {
            Map<Integer, String> map = new HashMap<Integer, String>();
            for (AuxStreamInfoEx auxStreamInfoEx : queryAuxStreamSourcesExResp.getAuxStreams())
            {
                map.put(auxStreamInfoEx.getId(), auxStreamInfoEx.getName());
            }
            resp.setResult(map);
        }
        LOGGER.info("queryAuxStreamSourcesEx method end");
        return resp;
    }
    
    public TPSDKResponseEx<List<VideoSourcesInfoEx>> queryVideoOutSrcStateEx(String siteURI)
    {
        LOGGER.info("queryVideoOutSrcStateEx method start");
        TPSDKResponseEx<List<VideoSourcesInfoEx>> resp = new TPSDKResponseEx<List<VideoSourcesInfoEx>>();
        QueryVideoOutSrcStateEx queryVideoOutSrcStateEx = new QueryVideoOutSrcStateEx();
        QueryVideoOutSrcStateExResponse queryVideoOutSrcStateExResp;
        queryVideoOutSrcStateEx.setSiteUri(siteURI);
        try
        {
            queryVideoOutSrcStateExResp = tPProfessionalSiteMgr.queryVideoOutSrcStateEx(queryVideoOutSrcStateEx);
        }
        catch (Exception e)
        {
            LOGGER.error("queryVideoOutSrcStateEx method error", e);
            ExceptionUtils.processSoapException(resp, e);
            return resp;
        }
        Integer resultCode = queryVideoOutSrcStateExResp.getResultCode();
        resp.setResult(0 == resultCode ? queryVideoOutSrcStateExResp.getVideoSourcesInfos() : null);
        resp.setResultCode(resultCode);
        LOGGER.info("queryVideoOutSrcStateEx method end");
        return resp;
    }
    
    public Integer ctrlCameraEx(String siteUri, CameraControlEx cameraControl)
    {
        LOGGER.info("ctrlCameraEx method start");
        CtrlCameraEx ctrlCameraEx = new CtrlCameraEx();
        ctrlCameraEx.setSiteUri(siteUri);
        ctrlCameraEx.setCameraControl(cameraControl);
        try
        {
            Integer errorCode = tPProfessionalSiteMgr.ctrlCameraEx(ctrlCameraEx).getResultCode();
            LOGGER.info("ctrlCameraEx method end");
            return errorCode;
        }
        catch (Exception e)
        {
            LOGGER.error("ctrlCameraEx method error", e);
            return ExceptionUtils.processSoapException(e);
        }
    }
    
    public Integer setMainAuxStreamSourcesEx(String siteUri, List<Integer> localMainSrc, Integer localAuxSrc)
    {
        LOGGER.info("setMainAuxStreamSourcesEx method start");
        SetMainAuxStreamSourcesEx setMainAuxStreamSourcesEx = new SetMainAuxStreamSourcesEx();
        setMainAuxStreamSourcesEx.setLocalAuxSrc(localAuxSrc);
        setMainAuxStreamSourcesEx.setLocalMainSrcs(localMainSrc);
        setMainAuxStreamSourcesEx.setSiteUri(siteUri);
        try
        {
            Integer errorCode =
                tPProfessionalSiteMgr.setMainAuxStreamSourcesEx(setMainAuxStreamSourcesEx).getResultCode();
            LOGGER.info("setMainAuxStreamSourcesEx method end");
            return errorCode;
        }
        catch (Exception e)
        {
            LOGGER.error("setMainAuxStreamSourcesEx method error", e);
            return ExceptionUtils.processSoapException(e);
        }
    }
    
    public TPSDKResponseEx<Map<Integer, String>> queryMainStreamSourcesEx(String siteUri)
    {
        LOGGER.info("queryMainStreamSourcesEx method start");
        TPSDKResponseEx<Map<Integer, String>> resp = new TPSDKResponseEx<Map<Integer, String>>();
        QueryMainStreamSourcesEx queryMainStreamSourcesEx = new QueryMainStreamSourcesEx();
        QueryMainStreamSourcesExResponse queryMainStreamSourcesExResp;
        queryMainStreamSourcesEx.setSiteUri(siteUri);
        try
        {
            queryMainStreamSourcesExResp = tPProfessionalSiteMgr.queryMainStreamSourcesEx(queryMainStreamSourcesEx);
        }
        catch (Exception e)
        {
            LOGGER.error("queryMainStreamSourcesEx method error", e);
            ExceptionUtils.processSoapException(resp, e);
            return resp;
        }
        Integer resultCode = queryMainStreamSourcesExResp.getResultCode();
        resp.setResultCode(resultCode);
        if (0 == resultCode)
        {
            Map<Integer, String> map = new HashMap<Integer, String>();
            for (AuxStreamInfoEx auxStreamInfoEx : queryMainStreamSourcesExResp.getAuxStreams())
            {
                map.put(auxStreamInfoEx.getId(), auxStreamInfoEx.getName());
            }
            resp.setResult(map);
        }
        LOGGER.info("queryMainStreamSourcesEx method end");
        return resp;
    }
    
    public Integer setVideoOutSrcEx(String siteUri, Integer hdOut, Integer videoSrc)
    {
        LOGGER.info("setVideoOutSrcEx method start");
        SetVideoOutSrcEx setVideoOutSrcEx = new SetVideoOutSrcEx();
        setVideoOutSrcEx.setSiteUri(siteUri);
        setVideoOutSrcEx.setHdOut(hdOut);
        setVideoOutSrcEx.setVideoSrc(videoSrc);
        try
        {
            Integer errorCode = tPProfessionalSiteMgr.setVideoOutSrcEx(setVideoOutSrcEx).getResultCode();
            LOGGER.info("setVideoOutSrcEx method end");
            return errorCode;
        }
        catch (Exception e)
        {
            LOGGER.error("setVideoOutSrcEx method error", e);
            return ExceptionUtils.processSoapException(e);
        }
    }
    
    public TPSDKResponseEx<SiteDeviceVersionInfoEx> querySiteVersionInfoEx(String siteURI)
    {
        LOGGER.info("querySiteVersionInfoEx method start");
        TPSDKResponseEx<SiteDeviceVersionInfoEx> resp = new TPSDKResponseEx<SiteDeviceVersionInfoEx>();
        QuerySiteVersionInfoEx querySiteVersionInfoEx = new QuerySiteVersionInfoEx();
        QuerySiteVersionInfoExResponse querySiteVersionInfoExResp;
        querySiteVersionInfoEx.setSiteUri(siteURI);
        
        try
        {
            querySiteVersionInfoExResp = tPProfessionalSiteMgr.querySiteVersionInfoEx(querySiteVersionInfoEx);
        }
        catch (Exception e)
        {
            LOGGER.error("querySiteVersionInfoEx method error", e);
            ExceptionUtils.processSoapException(resp, e);
            return resp;
        }
        Integer resultCode = querySiteVersionInfoExResp.getResultCode();
        resp.setResult(0 == resultCode ? querySiteVersionInfoExResp.getSiteDeviceVersionInfo() : null);
        resp.setResultCode(resultCode);
        LOGGER.info("querySiteVersionInfoEx method end");
        return resp;
    }
    
    public TPSDKResponseWithPageEx<List<TerminalInfoEx>> querySitesInfoEx(QueryConfigEx queryConfig)
    {
        LOGGER.info("querySitesInfoEx method start");
        TPSDKResponseWithPageEx<List<TerminalInfoEx>> resp = new TPSDKResponseWithPageEx<List<TerminalInfoEx>>();
        QuerySitesInfoExResponse response = null;
        try
        {
            QuerySitesInfoEx parameters = new QuerySitesInfoEx();
            parameters.setQueryConfig(queryConfig);
            response = tPProfessionalSiteMgr.querySitesInfoEx(parameters);
        }
        catch (Exception e)
        {
            LOGGER.error("querySitesInfoEx method error", e);
            ExceptionUtils.processSoapException(resp, e);
            return resp;
        }
        Integer resultCode = response.getResultCode();
        resp.setResultCode(resultCode);
        
        if (0 == resultCode)
        {
            List<TerminalInfoEx> sites = response.getSites();
            
            String decrytedPassword;
            for (TerminalInfoEx site : sites)
            {
                // 加密方式向下兼容
                if (!StringUtils.isEmpty(site.getRegPassword()))
                {
                    try
                    {
                        decrytedPassword = Encrypt.getEncryptPwd(site.getRegPassword());
                    }
                    catch (Exception e)
                    {
                        LOGGER.error("querySitesInfoEx method error", e);
                        ExceptionUtils.processSoapException(resp, e);
                        return resp;
                    }
                    site.setRegPassword(decrytedPassword);
                }
            }
            
            resp.setResult(sites);
            resp.setPageInfo(response.getPageInfo());
        }
        LOGGER.info("querySitesInfoEx method end");
        return resp;
    }
    
    public Integer addSiteInfoEx(String orgId, TerminalInfoEx siteInfo)
    {
        LOGGER.info("addSiteInfoEx method start");
        if (null != siteInfo && !StringUtils.isEmpty(siteInfo.getRegPassword()))
        {
            String encrytedPassword;
            try
            {
                // 加密方式向下兼容
                encrytedPassword = Encrypt.getEncryptPwd(siteInfo.getRegPassword());
                siteInfo.setRegPassword(encrytedPassword);
            }
            catch (Exception e)
            {
                LOGGER.error("encode password error");
                return PlatformNativeConstant.SDK_TP_PASSWORD_ENCODE_ERRORCODE;
            }
        }
        
        AddSiteInfoEx parameters = new AddSiteInfoEx();
        parameters.setOrgId(orgId);
        parameters.setSiteInfo(siteInfo);
        try
        {
            Integer errorCode = tPProfessionalSiteMgr.addSiteInfoEx(parameters).getResultCode();
            LOGGER.info("addSiteInfoEx method end");
            return errorCode;
        }
        catch (Exception e)
        {
            LOGGER.error("addSiteInfoEx method error", e);
            return ExceptionUtils.processSoapException(e);
        }
    }
    
    public Integer editSiteInfoEx(TerminalInfoEx siteInfo)
    {
        LOGGER.info("editSiteInfoEx method start");
        if (null != siteInfo && !StringUtils.isEmpty(siteInfo.getRegPassword()))
        {
            String encrytedPassword;
            try
            {
                // 加密方式向下兼容
                encrytedPassword = Encrypt.getEncryptPwd(siteInfo.getRegPassword());
                siteInfo.setRegPassword(encrytedPassword);
            }
            catch (Exception e)
            {
                LOGGER.error("encode password error");
                return PlatformNativeConstant.SDK_TP_PASSWORD_ENCODE_ERRORCODE;
            }
        }
        
        EditSiteInfoEx parameters = new EditSiteInfoEx();
        parameters.setSiteInfo(siteInfo);
        try
        {
            Integer errorCode = tPProfessionalSiteMgr.editSiteInfoEx(parameters).getResultCode();
            LOGGER.info("editSiteInfoEx method end");
            return errorCode;
        }
        catch (Exception e)
        {
            LOGGER.error("editSiteInfoEx method error", e);
            return ExceptionUtils.processSoapException(e);
        }
    }
    
    public Integer deleteSiteInfoEx(List<String> siteUris)
    {
        LOGGER.info("deleteSiteInfoEx method start");
        DeleteSiteInfoEx parameters = new DeleteSiteInfoEx();
        parameters.setSiteUris(siteUris);
        try
        {
            Integer errorCode = tPProfessionalSiteMgr.deleteSiteInfoEx(parameters).getResultCode();
            LOGGER.info("deleteSiteInfoEx method end");
            return errorCode;
        }
        catch (Exception e)
        {
            LOGGER.error("deleteSiteInfoEx method error", e);
            return ExceptionUtils.processSoapException(e);
        }
    }
}
